package cn.chendd.example.jpa.configuration;

import com.google.common.collect.Lists;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.jpa.repository.query.EscapeCharacter;
import org.springframework.data.jpa.repository.support.JpaRepositoryFactory;
import org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean;
import org.springframework.data.mapping.context.MappingContext;
import org.springframework.data.repository.Repository;
import org.springframework.data.repository.core.support.RepositoryFactorySupport;
import org.springframework.data.repository.core.support.TransactionalRepositoryFactoryBeanSupport;
import org.springframework.data.repository.query.ExtensionAwareQueryMethodEvaluationContextProvider;
import org.springframework.data.repository.query.QueryMethodEvaluationContextProvider;

import javax.annotation.Resource;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import java.util.Optional;

/**
 * Jpa Repository 工程类
 *
 * @author chendd
 * @date 2022/6/19 23:46
 */
public class JpaRepositoryFactoryBeanClass<T extends Repository<S , ID> , S , ID> extends TransactionalRepositoryFactoryBeanSupport<T , S , ID> {

    private EntityManager entityManager;
    private EscapeCharacter escapeCharacter = EscapeCharacter.DEFAULT;
    private Optional<MappingContext<?, ?>> mappingContext = Optional.empty();
    @Autowired(required = false)
    private JpaEvaluationContextExtension jpaEvaluationContextExtension;

    protected JpaRepositoryFactoryBeanClass(Class<? extends T> repositoryInterface) {
        super(repositoryInterface);
    }


    @PersistenceContext
    public void setEntityManager(EntityManager entityManager) {
        this.entityManager = entityManager;
    }

    @Override
    protected RepositoryFactorySupport doCreateRepositoryFactory() {
        JpaRepositoryFactory jpaRepositoryFactory = new JpaRepositoryFactory(entityManager);
        QueryMethodEvaluationContextProvider provider = new ExtensionAwareQueryMethodEvaluationContextProvider(
                Lists.newArrayList(jpaEvaluationContextExtension));
        jpaRepositoryFactory.setEvaluationContextProvider(provider);
        jpaRepositoryFactory.setEscapeCharacter(escapeCharacter);
        return jpaRepositoryFactory;
    }

    public void setEscapeCharacter(char escapeCharacter) {
        this.escapeCharacter = EscapeCharacter.of(escapeCharacter);
    }

    @Override
    protected void setMappingContext(MappingContext<?, ?> mappingContext) {
        super.setMappingContext(mappingContext);

    }

    public Optional<MappingContext<?, ?>> getMappingContext() {
        return mappingContext;
    }

    public void setMappingContext(Optional<MappingContext<?, ?>> mappingContext) {
        this.mappingContext = mappingContext;
    }
}
